Spring WebFlux 学习指南
1. WebFlux 概述
Spring WebFlux 是 Spring 5 引入的响应式编程框架,旨在提供非阻塞、事件驱动的 Web 应用开发能力。它基于 Reactive Streams 规范,可与 Reactor 框架配合使用,实现高并发和流式数据处理。
理解“流式”和“非阻塞”对系统性能和用户体验的提升是关键,尤其在 WebFlux 环境下,它们是优化并发能力的核心。
为了更好地体会这两者,我们可以通过以下几个方面的实际案例来理解:
非阻塞(Non-blocking): 非阻塞式编程意味着当程序执行某些操作(如数据库查询或外部服务调用)时,它不会阻塞当前线程的执行。相反,它会将当前任务交给事件循环线程,继续执行其他任务,当操作完成后再通知程序结果。这样做的优势是:可以在一个线程中同时处理多个请求,避免了传统阻塞方式下的线程等待,提高了系统的并发能力。
在传统的阻塞式编程中,我们可能会做如下操作:
1 | public KnowledgeBase getKnowledge(String id) { |
查询时整个线程被阻塞,直到查询完成返回结果。假设查询一个大数据集合或执行 AI 生成,这会导致服务器的线程被大量占用,造成延迟。
而在 WebFlux 中,这个操作会变成:
1 | public Mono<KnowledgeBase> getKnowledge(String id) { |
**非阻塞式 + 流式返回:**通过 WebFlux 和流式响应,我们可以将多个数据部分逐个返回,节省等待时间,提升系统并发能力。例如,在流式响应中,每部分返回数据都会在 Mono 和 Flux 上“等待”直到有结果生成,线程不会阻塞,而是可以处理其他请求。这对于需要长时间生成或处理的数据非常有效,比如 AI 内容生成、实时数据推送等。
2. Mono 与 Flux
WebFlux 主要依赖 Reactor 库,提供 Mono
和 Flux
作为响应式编程的核心数据类型。
- Mono:表示 0 或 1 个数据的流。
- Flux:表示 0-N 个数据的流。
示例:
1 | public Mono<String> getSingleData() { |
2.WebFlux 与 Spring MVC 的区别
特性 | Spring MVC | Spring WebFlux |
---|---|---|
编程模型 | 基于 Servlet (阻塞) | 基于 Reactive Streams (非阻塞) |
线程模型 | 每个请求一个线程 | 事件驱动,少量线程处理高并发 |
支持的服务器 | Tomcat, Jetty | Netty, Undertow, Tomcat, Jetty |
适用场景 | 传统 Web 应用 | 高并发、高吞吐、流式数据处理 |
官方对 Spring MVC 的定义:
Spring MVC 构建于 Servlet API 之上,使用的是同步阻塞式 I/O 模型,什么是同步阻塞式 I/O 模型呢?就是说,每一个请求对应一个线程去处理。
官方对 Spring WebFlux 的定义:
Spring WebFlux is a non-blocking web framework built from the ground up to take advantage of multi-core, next-generation processors and handle massive numbers of concurrent connections.
Spring WebFlux 是一个异步非阻塞式的 Web 框架,它能够充分利用多核 CPU 的硬件资源去处理大量的并发请求。
文档中有说到:WebFlux 并不能使接口的响应时间缩短,它仅仅能够提升吞吐量和伸缩性。
那么它就特别适合应用在 IO 密集型的服务中,比如微服务网关这样的应用中。
PS: IO 密集型包括:磁盘IO密集型, 网络IO密集型
3.选 WebFlux 还是 Spring MVC?
Spring MVC 是同步阻塞的,普通的单个服务优先 Spring MVC。
WebFlux 主要还是应用在异步非阻塞编程模型,如果服务中大量使用非同步方案,这时候才考虑 WebFlux 。
在微服务架构中,Spring MVC 和 WebFlux 可以混合使用(如上面说的网关)。
总结:WebFlux 不是 Spring MVC 的替代方案!
4、非阻塞 + 流式与 SSE/WebSocket
SSE(Server-Sent Events) 和 WebSocket 都可以用于 流式数据传输,而 WebFlux 提供了 非阻塞 的数据处理方式,因此 WebFlux 可以高效地与 SSE 和 WebSocket 结合使用。
结合 SSE 进行流式返回:
1 |
|
结合 WebSocket:
1 |
|
定义说明:
WebFlux 事件循环:同一个线程可以处理多个请求,遇到 I/O 操作(如数据库查询)时,释放线程继续处理其他请求,等 I/O 完成后通过回调恢复执行。
如果您觉得这篇博客对您有所帮助,欢迎分享给更多人。如果您发现博客中使用的图片存在版权问题,请及时联系作者,我们将尽快处理并删除相关内容。感谢您的支持!